home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-18 | 6.1 KB | 178 lines | [TEXT/R*ch] |
- Invoking Handlers in Scripts,
- by Name
-
- This is completely undocumented, as far as I know, but it may help. Suppose you
- have a script application containing a function:
-
- on DoSomething(param1,param2)
- return param1+param2
- end DoSomething
-
- From C, you just have to send the script application an Apple event like this
- one:
-
- CLASS: ascr
- type: psbr
- direct object: "----" "LIST"
- (the list of AEDescs of parameters to pass to the script function)
- additional parameter: "snam" "TEXT"
- containing the name of the function to call (in our example: “DoSomething”)
- et voilà.
-
- This method allows to write “clean” scripts, using more memorable handler names,
- not using the «CLASStype» syntax.
-
- Pierre-Loic Raynaud
-
-
-
- [This event is called “Subroutine Call” and is described in more detail in
- Chapter 10 of the Apple Event Registry, “The AppleScript Suite”. On the
- Developer Mailing Reference Library CD, the pdf file is named “AppleScript
- Suite”, and the information is on pdf page 5 (paper page 7). – jk]
-
-
-
-
- ***
-
-
-
- Swapping Bytes in a High Level Language,
- the Saga Continues!
- You have probably been swamped with everyone’s comments regarding the “Anti-Tip
- of the Month” that appeared in MacTech Magazine 11.10 (October 1995).
- Greg Poole had the right idea when he submitted his tip about byte-swapping.
- You can tweak code until your fingers fall off, but often the best way to make
- something faster is by finding a better way of doing the same thing.
- I have attached two files to this message: ByteSwap.c & ByteSwap.h. In a
- nutshell, we do our swapping as follows:
-
-
- ByteSwap.h
- #define SwapShort(myUnsignedShort) \
- ((myUnsignedShort)>>8)|((myUnsignedShort)<<8)
- In use:
- {
- unsigned short someValue = 0x3210;
- someValue = SwapShort(someValue);
- }
-
- We quite simply move the hi-byte right, and the lo-byte left, then OR them back
- together.
-
-
- ByteSwap.c
- #include "byteswap.h"
-
- unsigned long TransposeLong(unsigned long value)
- {
- unsigned long returnValue;
- ((unsigned char *) &returnValue)[3] =
- ((unsigned char *)
- &value)[0];
- ((unsigned char *) &returnValue)[2] =
- ((unsigned char *)
- &value)[1];
- ((unsigned char *) &returnValue)[1] =
- ((unsigned char *)
- &value)[2];
- ((unsigned char *) &returnValue)[0] =
- ((unsigned char *) &value)[3];
- return returnValue;
- }
- David
- Most
- The Technical Editor Responds
- There are quite a few methods available for byte swapping, but which algorithm
- is the best depends a great deal on the compiler and processor you are using.
- For instance, the PowerPC (and many other processors) have instructions
- specifically for this purpose. Unfortunately, since the C and C++ languages
- have not kept up with current processors (C is basically processor-independent
- PDP-11 assembly language), it is our job to trick the compiler into generating
- the correct code.
- Some compilers provide directives for this purpose. For instance, if you are
- using CodeWarrior on a PowerPC you can just say:
-
- inline long SwapLong(long val)
- {
- return __XXXXX(val); // <<<need intrinsic for load byte-swapped>>>
- }
- You may notice that I’m using C++ inline functions here instead of C #defines.
- To quote the “Apple Unofficial C++ Style Guide” (develop 2, p. 209): “One of the
- most powerful features of the C++ language is the C preprocessor. Don’t use it.”
- Inline functions are not only more readable than preprocessor macros, but,
- because they limit side effects, allow the compiler more latitude in optimizing
- your code.
- Barring that, we need to find something that we can say in C that can get bytes
- swapped without generating egregiously bad code. David’s solution is probably a
- good one for shorts because it is a pure mathematical expression, allowing the
- compiler to optimize it in any way it chooses. For longs, his solution is one
- of the safest, if you know nothing about the compiler and/or processor you’re
- building for. (I would, however, convert both to inline functions.)
- However, if you do know something about your processor, you can do better. In
- the case of the PPC, you really want to get your compiler to emit a load
- byte-swapped instruction. On a 680x0, you have a little latitude. One trick
- that comes to mind is that the 680x0 has predecrement and postincrement
- addressing modes. This means that:
-
- foo = *p++ and foo = *--p
- are fast and (1 instruction)
-
- foo = *++p and foo = *p--
- are slow (3 instructions). Therefore we can swap a long on a 680x0 with:
- inline long SwapLong(long val)
- {
- Byte* p = ((Byte*) val)[4]; // 680x0’s are big-endian
-
- long val = *--p;
- val = (val << 8) | *--p;
- val = (val << 8) | *--p;
- return (val << 8) | *--p;
- }
- The PowerPC has only post-increment instructions, so this will generate lousy
- code. (If someone would like to time a bunch of approaches, I’d be glad to
- publish the results.)
- I must say that the bottom line is: this is all a bunch of work that would be
- completely unnecessary if the C language had kept up with reality. Here’s my
- proposal to the ANSI committee:
- Make littleendian and bigendian storage classifiers like const and volatile.
- Then I could just type:
-
- typedef struct Foo
- {
- littleendian long bar;
- bigendian short baz;
- } Foo;
-
- void blah(Foo* foo)
- {
- long bar = foo->bar;
- short baz = foo->baz;
-
- ...
- }
- ...and let the compiler deal with it while I spend my time writing code which
- does real work.
- – sgs
-
-
- Fix For Tip Of The Month, January 1996
- I’m sending this short note just to point out that, although Greg Poole is right
- in writing that a file or directory can be moved by the CatMove function only if
- both the source and destination are on the same volume, he seems to forget that
- every Macintosh volume, not just the System volume, has a Trash folder.
- Thus, if we pass to the FindFolder function the volume reference number of the
- file to be deleted instead of the constant kOnSystemDisk, we will be able to
- find the directory ID of the local Trash.
-
- Line #44 of “FSpTrashFile.c” source file should be changed from:
- theErr = FindFolder( kOnSystemDisk, kTrashFolderType,
- kDontCreateFolder, &vRefNum, &dirID );
- to:
- theErr = FindFolder( (*theFile).vRefNum, kTrashFolderType,
- kDontCreateFolder, &vRefNum, &dirID );
- Live Long and Prosper!
-
- Luigi Belverato
-